home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok22.lha
/
CrossRef
/
Cross.dok
< prev
next >
Wrap
Text File
|
1993-08-15
|
8KB
|
237 lines
CrossReference - Lister
=============================
Version 1.00
geschrieben von Andreas Pahl
13.07.1989
Kopierrecht
------------
Das komplette Packet (Quelltext, Dokumentation und Objectcode) ist
Public Domain Software. Es darf beliebig kopiert und verbreitet werden
solange...
* mein Name und dieser Kopierrechtshinweis erhalten bleiben,
* die Vollständigkeit des ganzen Packets gewährleistet ist, und
* mit dem Vertrieb dieser Software kein Gewinn erwirtschaftet wird.
Die Kommerzielle Nutzung ohne meine ausdrückliche schriftliche
Genehmigung ist untersagt. Falls Sie dies beabsichtigen, nehmen Sie
bitte unter unten genannter Adresse Kontakt mit mir auf.
Einleitung :
------------
Ein CrossReference-Lister durchsucht den Sourcecode nach allen
Bezeichnern, zählt ihr Vorkommen und gibt alle Zeilennummern aus,
in denen die Bezeichner verwendet werden.
Programm :
----------
Das Programm läßt sich zur Zeit eigentlich nur sinnvoll in Verbindung
mit Modlist (eventuell werde ich in Zukunft daran koppeln) oder mit
einem Editor, bei dem es eine Statuszeile gibt, in der die aktuelle
Zeilennummer steht (z.B. DME), verwenden. Aber ich habe noch eine
ganze Menge Ideen, das Programm wird also sicherlich noch weiterentwickelt.
Die grundlegende Datenstruktur des Programms ist ein sogenannter Trie.
Ein Trie ist ein Vielwegbaum, in dessen Knoten einzelne Buchstaben eines
Wortes gespeichert sind. Folgt man von der Wurzel des Trie allen möglichen
Pfaden bis zu seiner Wortendmarke, erhält man alle im Trie gespeicherten
Worte. Ein Beispieltrie, gebildet aus den Worten BALL, BAR, BAU, BAUM,
BIER, BILD, IOD :
Wurzel
______/ \__
_____/ \__
B I
__/ \__ |
__/ \__ |
A I O
/|\ / \ |
/ | \ / \ |
L *R U E L *D
| | | |
| | | |
*L *M *R *D * ist die Wortendmarke
Diese Datenstruktur eignet sich besonders gut, um eingelesene Wörter
alphabetisch zu speichern. Würde man die oben gezeigte Struktur so in
Modula implementieren, würde das allerdings eine enorme Speicherplatz-
verschwendung bedeuten, da man zu jedem Knoten 52 Nachfolger definieren
müßte (je 26 Groß- und Kleinbuchstaben unter Vernachlässigung der Umlaute),
von denen jedoch nie alle gebraucht werden. Deshalb führt man eine
Modifikation ein und definiert einfach für jeden Knoten einen horizontalen
und einen vertikalen Nachfolgerknoten. Jetzt werden nur Knoten generiert,
die auch wirklich benutzt werden.
Wurzel
______/
_____/
B------------------------>I
__/ |
__/ |
A------------>I O
/ / |
/ / |
L-->*R-->U E---->L *D
| | | |
| | | |
*L *M *R *D * ist die Wortendmarke
Dazu gehört folgende Deklaration:
Trie = POINTER TO Node;
Node = RECORD
Buchstabe : CHAR;
Anzahl : CARDINAL; (* Häufigkeit des Bezeichners *)
Wortende : BOOLEAN; (* Markiert Wortende im Trie *)
horizontal,
vertikal : Trie;
END;
Beim Trie wird der zu analysierende Text nun Zeichen für Zeichen eingelesen
und direkt ohne Zwischenspeicherung im Trie gespeichert. Die zentrale
Prozedur, die das bewirkt, ist die Prozedur INSERT. Jedesmal, wenn der
erste Buchstabe eines Wortes eingelesen wurde, wird INSERT aufgerufen und zu
dem Trieknoten verzweigt, der diesem ersten Buchstaben entspricht. Dann
erst wird der nächste Buchstabe gelesen und derjenige Nachfolgerknoten
gesucht, der diesem Buchstaben entspricht. Falls kein solcher Nachfolger
existiert, wird ein neuer Knoten geschaffen. Dieses Verfahren wird solange
weitergeführt, bis der letzte Buchstabe des Wortes gelesen und das Wort
somit an der richtigen Stelle im Wörterbuch eingetragen ist.
Pseudocode von INSERT:
----------------------
(* Beim ersten Aufruf sei der erste Buchstabe des Wortes bereits gelesen.
Das gerade aktuell gelesene Zeichen sei ZEICHEN. TRIE ist gemäß obiger
Deklaration vereinbart. *)
Prozedur Insert(VAR KNOTEN:TRIE);
BEGIN
Falls KNOTEN auf NIL zeigt,
dann alloziere Speicherplatz für einen neuen Knoten,
speichere darin ZEICHEN und laß KNOTEN auf diesen neuen Knoten zeigen.
Wandern: Lies das nächste Zeichen ZEICHEN.
Falls es sich bei ZEICHEN um einen Buchstaben handelt,
dann plaziere ihn am richtigen Ort im TRIE durch
Aufruf von Insert(KNOTEN^.vertikal),
sonst KNOTEN^.Wortende := TRUE
Falls KNOTEN nicht auf NIL zeigt, sondern auf einen Knoten mit einem
Buchstaben, der alphabetisch nach ZEICHEN kommt,
dann füge ZEICHEN vor diesem Knoten in den TRIE ein,
indem du einen neuen Knoten bildest, darin ZEICHEN speicherst und den
Horizontalzeiger dieses neuen Knotens auf den gleichen Ort richtest, auf
den KNOTEN zeigt. Anschließend soll KNOTEN neu auf den neuen Knoten
zeigen.
Führe die gleichen Aktionen aus, wie unter Wandern beschrieben.
Falls KNOTEN nicht auf NIL zeigt, sondern auf einen Knoten mit einem
Buchstaben, der alphabetisch vor ZEICHEN kommt,
dann füge ZEICHEN nach diesem KNOTEN in den TRIE ein durch
Aufruf Insert(KNOTEN^.horizontal).
Falls KNOTEN nicht auf NIL zeigt, sondern auf einen Knoten mit denselben
Buchstaben wie ZEICHEN,
dann führe die Aktion durch, die unter Wandern beschrieben sind.
END Insert;
Aufruf des Programms
--------------------
Das Programm fragt nach derSourcedatei und nach der Ausgabedatei. Die
Sourcedatei kann gleich als Parameter beim Start vom CLI aus mit übergeben
werden.
Bedeutung der Buchstaben in der Spalte Typ:
-------------------------------------------
M = Modul
F = Importiertes Modul
I = Importierter Bezeichner
P = Prozedur
C = Konstante
T = Typ
V = Variable
B = implizit importierter Bezeichner
(z.B. beim Importiern von Records oder Mengen. Dabei
erscheint nur der Name des Records bzw. der Menge in der
Import-Liste, aber nicht alle Elemente, die ja auch vom
Programm benutzt werden können)
Mögliche Erweiterungen:
-----------------------
- Zeilenbreite entsprechend Ausgabegerät
- Anzeigen, wo der Bezeichner definiert ist (Welches Modul, welche
Prozedur)
- Was das Programm alles anzeigen soll, irgendwie vom Benutzer wählen
lassen
(aber mit Voreinstellung)
- Mit Modlist verbinden
- Schachtelungstiefe ausgeben
- Smart-Linker auf Sourceebene
- Zu jeder Prozedur alle Bezeichner herausschreiben, die in ihr
verwendet, aber nicht deklariert werden. Hilfreich für Programm-
modifikationen und gegen unerwünschte Seiteneffekte
Falls jemand Fehler findet, so möge er sie mir doch bitte mitteilen. Auch
Verbesserungswünsche sind jederzeit willkommen.
Viel Spaß, Andreas
Adresse:
---------
Andreas Pahl
Zikadenweg 22
D-1000 Berlin 19
Tel. 030/302 55 37
EMail-Adressen:
---------------
UUCP: Domain : macbeth@netmbx.UUCP
Bang : ...{pyramid|altger|tub|unido}!tmpmbx!netmbx!macbeth
FidoNet: 2:242/1000 TO:Andreas Pahl
2:242/9000.43 TO:Andreas Pahl